package com.lant.service.impl;

import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.lant.constant.FieldConstant;
import com.lant.dao.LantUserDao;
import com.lant.enums.ResponseStatusEnum;
import com.lant.enums.UserCheckEnum;
import com.lant.pojo.LantResult;
import com.lant.pojo.LantUser;
import com.lant.pojo.LantUserExample;
import com.lant.pojo.LantUserExample.Criteria;
import com.lant.service.LantUserService;
import com.lant.utils.CookieUtils;
import com.lant.utils.ExceptionUtil;
import com.lant.utils.JsonUtils;
import com.lant.utils.ObjectUtils;
import com.lant.utils.RedisUtil;

@RestController
@FeignClient(value = "redis-provider")
@RequestMapping("/user")
public class LantUserServiceImpl implements LantUserService {
    private static final Logger logger = LoggerFactory.getLogger(LantUserServiceImpl.class);
    @Autowired
    private LantUserDao lantUserDao;

    private static final String SERVICE_EXCEPTION = "服务出现异常，请联系管理员";
    private static final String WRONG_USER_NAME_OR_PASSWORD = "用户名或密码错误";
    private static final String THIS_ACCOUNT_HAS_EXPIRED = "此账号已经过期请重新登录";

    @RequestMapping(value = "/checkData", method = RequestMethod.POST)
    @Override
    public LantResult checkData(String content, Integer type) {
        try {
            LantUserExample lantUserExample = new LantUserExample();
            Criteria criteria = lantUserExample.createCriteria();
            // 对数据进行校验
            // 1.校验username
            if (UserCheckEnum.USER_NAME.getValue() == type) {
                // 用户名校验
                criteria.andUserNameEqualTo(content);
            } else if (UserCheckEnum.MOBILE.getValue() == type) {
                // 电话校验
                criteria.andMobileEqualTo(content);
            } else {
                // email校验
                criteria.andEmailEqualTo(content);
            }
            // 执行查询
            List<LantUser> list = lantUserDao.selectByExample(lantUserExample);
            if (ObjectUtils.isEmpty(list)) {
                return LantResult.ok(true);
            }
        } catch (Exception e) {
            logger.error(SERVICE_EXCEPTION, e.getMessage());
            return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
        }

        return LantResult.ok(false);
    }

    @RequestMapping(value = "/createUser", method = RequestMethod.POST)
    @Override
    public LantResult createUser(String userJson) {
        try {
            LantUser user = LantResult.toJavaObject(userJson, LantUser.class);
            user.setLastAccess(System.currentTimeMillis());
            user.setCreateTime(System.currentTimeMillis());
            // 密码MD5加密
            String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
            user.setPassword(password);
            lantUserDao.insertSelective(user);

            return LantResult.ok();
        } catch (Exception e) {
            logger.error(SERVICE_EXCEPTION, e.getMessage());
            return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
        }
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @Override
    public LantResult login(String userName, String password, HttpServletRequest request,
        HttpServletResponse response) {
        try {
            // 创建查询条件
            LantUserExample example = new LantUserExample();
            Criteria criteria = example.createCriteria();
            criteria.andUserNameEqualTo(userName);
            // 查询用户
            List<LantUser> list = lantUserDao.selectByExample(example);
            if (ObjectUtils.isEmpty(list)) {
                logger.error(WRONG_USER_NAME_OR_PASSWORD);
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), WRONG_USER_NAME_OR_PASSWORD);
            }

            LantUser user = list.get(0);
            // 加密密码
            password = DigestUtils.md5DigestAsHex(password.getBytes());
            if (!password.equals(user.getPassword())) {
                logger.error(WRONG_USER_NAME_OR_PASSWORD);
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), WRONG_USER_NAME_OR_PASSWORD);
            }
            // 生成token
            String token = UUID.randomUUID().toString();
            // 保存用户之前，把用户对象的密码清理掉
            user.setPassword(null);
            String userJson = JsonUtils.objectToJson(user);
            // 把用户信息写入redis
            String key = String.format(FieldConstant.getRedisUserSessionKey(), token);

            try {
                RedisUtil.set(key, userJson, FieldConstant.getSSOSessionExpire());
            } catch (Exception e) {
                // 查看接口调用是否正常
                logger.error(SERVICE_EXCEPTION, e.getMessage());
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
            }

            // 添加cookie逻辑,关闭浏览器失效（默认的）
            CookieUtils.setCookie(request, response, FieldConstant.getLantToken(), token);

            return LantResult.ok(token);
        } catch (Exception e) {
            logger.error(SERVICE_EXCEPTION, e.getMessage());
            return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
        }
    }

    @RequestMapping(value = "/getUserByToken", method = RequestMethod.POST)
    @Override
    public LantResult getUserByToken(String token) {
        try {
            // 通过token查询redis中用户信息
            String key = String.format(FieldConstant.getRedisUserSessionKey(), token);

            LantResult result;
            try {
                // 调用token接口返回
                result = RedisUtil.get(key);
            } catch (Exception e) {
                logger.error(SERVICE_EXCEPTION, e.getMessage());
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
            }

            Object data = result.getData();

            if (ObjectUtils.isNull(data)) {
                logger.error(THIS_ACCOUNT_HAS_EXPIRED);
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), THIS_ACCOUNT_HAS_EXPIRED);
            }

            // 调用更新过期时间
            try {
                RedisUtil.expire(key, FieldConstant.getSSOSessionExpire());
            } catch (Exception e) {
                logger.error(SERVICE_EXCEPTION, e.getMessage());
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
            }

            // 返回用户信息
            return LantResult.ok(JsonUtils.jsonToPojo(data.toString(), LantUser.class));
        } catch (Exception e) {
            logger.error(SERVICE_EXCEPTION, e.getMessage());
            return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
        }
    }

    @RequestMapping(value = "/logoff", method = RequestMethod.POST)
    @Override
    public LantResult logoffUserByToken(String token) {
        try {
            // 通过token查询redis中用户信息
            String key = String.format(FieldConstant.getRedisUserSessionKey(), token);

            LantResult result;
            try {
                result = RedisUtil.get(key);
            } catch (Exception e) {
                logger.error(SERVICE_EXCEPTION, e.getMessage());
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
            }

            Object data = result.getData();

            if (ObjectUtils.isNull(data)) {
                logger.error(THIS_ACCOUNT_HAS_EXPIRED);
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), THIS_ACCOUNT_HAS_EXPIRED);
            }

            // 删除token
            try {
                RedisUtil.del(key);
            } catch (Exception e) {
                logger.error(SERVICE_EXCEPTION, e.getMessage());
                return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
            }

            return LantResult.ok();
        } catch (Exception e) {
            logger.error(SERVICE_EXCEPTION, e.getMessage());
            return LantResult.build(ResponseStatusEnum.BAD_REQUEST.getValue(), ExceptionUtil.getStackTrace(e));
        }
    }
}
